package com.sxf.core.db.datasource;

import com.sxf.common.exceptions.BusinessException;
import com.sxf.core.db.common.DynamicDataSourceGlobal;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 
 * @description: 动态数据源
 * @author: zhangyb@ccccit.com.cn
 * @date: 2021年1月7日 下午4:47:43
 */
public class DynamicDataSource extends AbstractRoutingDataSource {

    /**
     * 写数据源
     */
    private Object writeDataSource;

    /**
     * 读数据源
     */
    private Object readDataSource;

    /**
     * 设置数据源使用策略
     */
    @Override
    public void afterPropertiesSet() {
        if (this.writeDataSource == null) {
            throw new BusinessException("数据源获取失败");
        }

        /**
         * 设置默认数据源
         */
        setDefaultTargetDataSource(writeDataSource);

        /**
         * 设置数据源map
         */
        Map<Object, Object> targetDataSources = new HashMap<>(2);
        targetDataSources.put(DynamicDataSourceGlobal.WRITE.name(), writeDataSource);
        if (readDataSource != null) {
            targetDataSources.put(DynamicDataSourceGlobal.READ.name(), readDataSource);
        }
        setTargetDataSources(targetDataSources);
        super.afterPropertiesSet();
    }

    /**
     * 轮训，返回数据源map中的key，每次调用时都会先轮训
     */
    @Override
    protected Object determineCurrentLookupKey() {
        String datasourceKey = DynamicDataSourceGlobal.WRITE.name();
        
        if(Objects.isNull(DynamicDataSourceHolder.getDataSource())) {
            return datasourceKey;
        }
        
        datasourceKey = DynamicDataSourceHolder.getDataSource().name();
        DynamicDataSourceHolder.clearDataSource();
        
        return datasourceKey;
    }
    
    

    public void setWriteDataSource(Object writeDataSource) {
        this.writeDataSource = writeDataSource;
    }

    public Object getWriteDataSource() {
        return writeDataSource;
    }

    public Object getReadDataSource() {
        return readDataSource;
    }

    public void setReadDataSource(Object readDataSource) {
        this.readDataSource = readDataSource;
    }

}
